 """This is a firebird database manipulator"""

from mydb.basic import base as superbase
from mydb.basic import relations as superrelations
from mydb.basic import view as superview
from mydb.basic import table as supertable
from mydb.basic import aview as superaview
from mydb.basic import atable as superatable

import fdb

class base(superbase):
	"This class is a base connector"
	#print (self.__doc__)
	#beginning of class suite
	def __init__(self):
		super(base, self).__init__()
		self.driver=fdb
		self.user=''
		self.passwd=''
		self.host=''
		self.base=''
		self.variable='?'
	
	def open(self):
		"This function opens connection to base"
		#print (self.open.__doc__)
		#beginning of function suite
		self.conn = self.driver.connect(host=self.host, database=self.base, user=self.user, password=self.passwd)
		self.cursor = self.conn.cursor()
		#end of function suite
		return

	def execute_in_cycle(self, string, row=None):
		"This function executes statement against base optional for row of values"
		#beginning of function suite
		if not row:
			self.cursor.execute(string)
		else:
			self.cursor.execute(string, [row])
		self.conn.commit()
		#end of function suite
		#Функция ничего не возвращает
		return

	def execute_many_in_cycle(self, string, rows):
		"This function executes a statement for rows of values"
		#beginning of function suite
		#Выполняется запрос в зависимости от наличия аргументов
		self.cursor.executemany(string, rows)
		self.conn.commit()
		#end of function suite
		#Функция возвращает результат запроса
		return

	def fetch_in_cycle(self, string, row=None, lim=0):
		"This function fetches a statement optional for row of values"
		#beginning of function suite
		if not row:
			self.cursor.execute(string)
		else:
			self.cursor.execute(string, [row])
		if lim==0:
			result=self.cursor.fetchall()
		else:
			result=self.cursor.fetchmany(lim)
		return result
		#end of function suite
		#Функция возвращает результат запроса

	def commit_in_cycle(self, string):
		"This function executes statement against base and commits it"
		#beginning of function suite
		#Выполняется запрос
		self.conn.execute_immediate(string)
		self.conn.commit()
		#end of function suite
		return

	def execute(self, string, row=None):
		"This function connects to base and executes a statement optional for row of values"
		#beginning of function suite
		#Выполняется подключение к базе данных
		self.connect()
		#Выполняется запрос в зависимости от наличия аргументов
		if not row:
			self.cursor.execute(string)
		else:
			self.cursor.execute(string, [row])
		self.conn.commit()
		#Выполняется отключение от базы данных
		self.disconnect()
		#end of function suite
		#Функция ничего не возвращает
		return

	def fetch(self, string, row=None, lim=0):
		"This function connects to base and fetches a statement optional for row of values"
		#beginning of function suite
		#Выполняется подключение к базе данных
		self.connect()
		#Выполняется запрос в зависимости от наличия аргументов
		if not row:
			self.cursor.execute(string)
		else:
			self.cursor.execute(string, [row])
		if lim==0:
			result=self.cursor.fetchall()
		else:
			result=self.cursor.fetchmany(lim)
		self.disconnect()
		return result
		#end of function suite
		#Функция возвращает результат запроса

	def generate(self, string, row=None, lim=1000):
		"This function connects to base and fetches a statement optional for row of values"
		#beginning of function suite
		#Выполняется подключение к базе данных
		self.connect()
		#Выполняется запрос в зависимости от наличия аргументов
		if not row:
			self.cursor.execute(string)
		else:
			self.cursor.execute(string, [row])
			
		while True:
			results=self.cursor.fetchmany(lim)
			if results==[]: 
				self.disconnect()
				break
			for result in results:
				yield result
		#end of function suite
		#Функция возвращает генератор результатов запроса

	def iterate(self, string, row=None, start=None, stop=None, step=None):
		"This function connects to base and executes a statement optional for a row of values"
		#beginning of function suite
		#end of function suite
		#Функция возвращает итератор результатов запроса
		return islice(self.generate(string, row), start, stop, step)

	def execute_many(self, string, rows):
		"This function connects to base and executes a statement for rows of values"
		#beginning of function suite
		#Выполняется подключение к базе данных
		self.connect()
		#Выполняется запрос в зависимости от наличия аргументов
		self.cursor.executemany(string, rows)
		self.conn.commit()
		#Выполняется отключение от базы данных
		self.disconnect()
		#end of function suite
		#Функция возвращает результат запроса
		return

	def commit(self, string):
		"This function connects to base, executes a statement and commits it"
		#beginning of function suite
		#Выполняется подключение к базе данных
		self.connect()
		#Выполняется запрос
		self.conn.execute_immediate(string)
		self.conn.commit()
		#Выполняется отключение от базы данных
		self.disconnect()
		#end of function suite
		return

#end of  class base suite

class relations(superrelations):
		"This class counts and select records for relations"
		#beginning of class suite
		#print (self.__doc__)
		#Инициализация:
		def __init__(self):
			super(relations, self).__init__()
			self.base=base()
#			self.variable='?'

		def catalogue(self, type):
			return 'RDB$RELATIONS'  

		def field(self, type):
			return 'TRIM(RDB$RELATION_NAME)'
		
		def condition(self, type, word):
			'Function returns base specific condition for table/view catalogue'
			if word.lower()=='where':
				result=' '+'WHERE'+' '+'RDB$SYSTEM_FLAG=0'+' '+'AND'+' '+'(RDB$RELATION_TYPE IN'+' '+type
			elif word.lower()=='and':
				result=' '+'AND'+' '+'RDB$SYSTEM_FLAG=0'+' '+'AND'+' '+'(RDB$RELATION_TYPE IN'+' '+type
			return result
		
		def type(self,type):
			'Function returns base specific type sign'
			dict={'t':'(0))','v':'(1))','a':'(0,1,3) OR RDB$RELATION_TYPE IS NULL)'}
			return dict[type]

		#Определяется функция выборки похожих таблиц и видов
		def SelectlikeAny(self,names=['']):
			'''Function selects like any'''
			#beginning of function suite
			#print(self.SelectlikeAny.__doc__)
			#end of function suite
			#Функция возвращает выборку таблиц и видов с похожими именами
			return self.select(True, self.type('a'), names)

		#Определяется функция выборки таблиц и видов
		def SelectAny(self,names=['']):
			'''Function selects any'''
			#beginning of function suite
			#print(self.SelectAny.__doc__)
			#end of function suite
			#Функция возвращает выборку таблиц и видов с заданными именами
			return self.select(False, self.type('a'), names)
		
		#Определяется функция подсчета количества похожих таблиц и видов
		def CountlikeAny(self,names=['']):
			'''Function counts any'''
			#beginning of function suite
			#print(self.CountlikeAny.__doc__)
			#end of function suite
			#Функция возвращает число таблиц и видов с похожим именами
			return self.count(True, self.type('a'), names)
		
		#Определяется функция подсчета количества таблиц и видов
		def CountAny(self,names=['']):
			'''Function counts any'''
			#beginning of function suite
			#print(self.CountAny.__doc__)
			#end of function suite
			#Функция возвращает число таблиц и видов с заданными именами
			return self.count(False, self.type('a'),names)

	#end of class relations suite

class view(superview):
	"This class is a manipulater for views"
	#beginning of class suite
	#print (self.__doc__)
	#Инициализация:
	def __init__(self):
		super(view, self).__init__()
		self.base=base()
		self.relations=relations()
		self.relations.base=self.base

	def countself(self, name):
		'''Function counts any with the name of the view'''
		#beginning of function suite
		#print(self.count.__doc__)
		#end of function suite
		#Функция возвращает результат выполнения функции self.relations.CountAny() с именем вида в качестве аргумента
		return self.relations.CountAny([self.SqlCase(name)])

	#end of class view suite

class table(supertable):
	"This class is a manipulater for views"
	#beginning of class suite
	#print (self.__doc__)
	#Инициализация:
	def __init__(self):
		super(table, self).__init__()
		self.base=base()
		self.relations=relations()
		self.relations.base=self.base
		self.seq_postfix='_GEN'
		self.constraint_postfix='_NDX'

	def countself(self, name):
		'''Function counts tables with the name of the table'''
		#beginning of function suite
		#print(self.count.__doc__)
		#end of function suite
		#Функция возвращает результат выполнения функции self.relations.CountAny() с именем вида в качестве аргумента
		return self.relations.CountAny([self.SqlCase(name)])

	#end of class table suite

class aview(superaview):
	"This class is a manipulator for a view"
	#beginning of class suite
	#print (self.__doc__)
	def __init__(self):
		super(aview, self).__init__()
		self.view=view()

	#end of class aview suite

class atable(superatable):
	"This class is a manipulator for a table"
	#beginning of class suite
	#print (self.__doc__)
	def __init__(self):
		super(atable, self).__init__()
		self.table=table()

	#end of class atable suite
